# coding=utf-8
import arcpy
import os
import sys

# 设置默认编码为 UTF-8
try:
    reload(sys)
    sys.setdefaultencoding('utf-8')
except NameError:
    # Python 3 不需要此操作
    pass


# 配置参数 - 直接指定具体数据路径
class Config:
    OLD_FEATURE_CLASS = r"D:\ArcGis\DATA\19_test.gdb\DMGC_DLZCXX_polygon_add"  # 旧数据路径
    NEW_FEATURE_CLASS = r"D:\ArcGis\DATA\24_test.gdb\DLPL_ZCJCXX"  # 新数据路径


def create_gdb_if_not_exists(gdb_path):
    """创建文件地理数据库（如果不存在）"""
    try:
        if not arcpy.Exists(gdb_path):
            # 确保父目录存在
            parent_dir = os.path.dirname(gdb_path)
            if not os.path.exists(parent_dir):
                os.makedirs(parent_dir)
            arcpy.CreateFileGDB_management(os.path.dirname(gdb_path), os.path.basename(gdb_path))
            print("成功创建地理数据库: %s" % gdb_path)
        return True
    except Exception as e:
        print("创建地理数据库失败: %s, 错误: %s" % (gdb_path, str(e)))
        return False


def ensure_fields_with_z(feature_class, has_z=True, has_m=True):
    """确保要素类包含必要字段并支持Z/M值"""
    try:
        fields = [f.name.upper() for f in arcpy.ListFields(feature_class)]

        # 检查并启用Z/M值
        desc = arcpy.Describe(feature_class)
        if has_z and not desc.hasZ:
            print("警告: 要素类 %s 不支持Z值" % os.path.basename(feature_class))

        if has_m and not desc.hasM:
            print("警告: 要素类 %s 不支持M值" % os.path.basename(feature_class))

        return True
    except Exception as e:
        print("处理要素类字段失败: %s, 错误: %s" % (feature_class, str(e)))
        return False


def add_field_and_initialize(fc, field_name, field_type, default_value):
    """添加字段并初始化为短整型"""
    fields = [f.name.upper() for f in arcpy.ListFields(fc)]
    if field_name.upper() not in fields:
        # 确保类型为短整型
        if field_type.upper() in ['SHORT', 'SMALLINT', 'SMALLINTEGER']:
            field_type = 'SHORT'  # 统一映射为SHORT
        else:
            print("警告: 字段 %s 应设置为SHORT类型，当前类型: %s" % (field_name, field_type))
            field_type = 'SHORT'

        arcpy.AddField_management(fc, field_name, field_type)
        with arcpy.da.UpdateCursor(fc, [field_name]) as cursor:
            for row in cursor:
                row[0] = default_value
                cursor.updateRow(row)
        print("成功添加短整型字段: %s, 初始值: %s" % (field_name, default_value))
    else:
        # 验证现有字段类型是否为SHORT或等效类型
        existing_type = arcpy.ListFields(fc, field_name)[0].type
        if existing_type.upper() not in ['SHORT', 'SMALLINT', 'SMALLINTEGER']:
            print("警告: 已存在的字段 %s 类型为 %s，非SHORT等效类型" % (field_name, existing_type))
        else:
            print("字段 %s 已存在，类型正确: SHORT" % field_name)


def add_missing_fields(new_fc, old_fc):
    """将旧数据中存在而新数据中不存在的属性字段添加到新数据中，全部初始化为空"""
    old_fields = arcpy.ListFields(old_fc)
    new_fields = [f.name.upper() for f in arcpy.ListFields(new_fc)]

    # 定义ArcGIS支持的字段类型
    supported_types = ['TEXT', 'FLOAT', 'DOUBLE', 'SHORT', 'LONG', 'DATE', 'BLOB', 'RASTER', 'GUID']

    # 字段类型映射表（处理不同名称但等效的类型）
    type_mapping = {
        'SMALLINT': 'SHORT',
        'SMALLINTEGER': 'SHORT',
        'STRING': 'TEXT',  # 处理字符串类型
        # 可添加更多映射
    }

    for field in old_fields:
        # 跳过系统字段
        if field.name.upper() in ['OBJECTID', 'SHAPE', 'SHAPE_LENGTH', 'SHAPE_AREA']:
            continue

        if field.name.upper() not in new_fields:
            field_name = field.name
            field_type = field.type.upper()

            # 应用类型映射
            field_type = type_mapping.get(field_type, field_type)

            # 检查字段类型是否支持
            if field_type not in supported_types:
                print("错误: 字段 '%s' 的类型 '%s' 不支持 ArcGIS 标准类型" % (field_name, field_type))
                print("支持的类型: TEXT | FLOAT | DOUBLE | SHORT | LONG | DATE | BLOB | RASTER | GUID")
                print("将字段 '%s' 的类型转换为 TEXT 类型" % field_name)
                field_type = 'TEXT'

            try:
                arcpy.AddField_management(new_fc, field_name, field_type)
                with arcpy.da.UpdateCursor(new_fc, [field_name]) as cursor:
                    for row in cursor:
                        row[0] = None
                        cursor.updateRow(row)
                print("成功添加字段: %s (类型: %s)" % (field_name, field_type))
            except Exception as e:
                print("添加字段 '%s' 失败，类型: %s" % (field_name, field_type))
                print("错误详情: %s" % str(e))


def copy_old_to_new(new_fc, old_fc):
    """将旧数据全部复制到新数据中，字段要求一一对应，旧数据没有的字段设为空"""
    old_fields = [f.name for f in arcpy.ListFields(old_fc)]
    new_fields = [f.name for f in arcpy.ListFields(new_fc)]

    # 过滤掉系统字段
    old_fields = [f for f in old_fields if f.upper() not in ['OBJECTID', 'SHAPE', 'SHAPE_LENGTH', 'SHAPE_AREA']]
    new_fields = [f for f in new_fields if f.upper() not in ['OBJECTID', 'SHAPE', 'SHAPE_LENGTH', 'SHAPE_AREA']]

    # 添加几何字段
    old_fields.append('SHAPE@')
    new_fields.append('SHAPE@')

    # 构建插入字段映射
    insert_fields = []
    for field in new_fields:
        if field in old_fields:
            insert_fields.append(field)
        else:
            insert_fields.append(None)

    # 执行数据复制
    print("开始复制数据...")
    count = 0
    with arcpy.da.InsertCursor(new_fc, new_fields) as insert_cursor:
        with arcpy.da.SearchCursor(old_fc, old_fields) as search_cursor:
            for row in search_cursor:
                new_row = []
                for field in insert_fields:
                    if field is None:
                        new_row.append(None)
                    else:
                        index = old_fields.index(field)
                        new_row.append(row[index])
                insert_cursor.insertRow(new_row)
                count += 1
                if count % 1000 == 0:
                    print("已处理 %d 条记录" % count)
    print("共复制 %d 条记录" % count)


if __name__ == "__main__":
    try:
        print("===== 开始执行数据处理 =====")
        print("旧数据: %s" % Config.OLD_FEATURE_CLASS)
        print("新数据: %s" % Config.NEW_FEATURE_CLASS)

        # 检查输入数据是否存在
        if not arcpy.Exists(Config.OLD_FEATURE_CLASS):
            raise Exception("旧数据不存在: %s" % Config.OLD_FEATURE_CLASS)

        if not arcpy.Exists(Config.NEW_FEATURE_CLASS):
            raise Exception("新数据不存在: %s" % Config.NEW_FEATURE_CLASS)

        # 设置地理处理环境
        arcpy.env.overwriteOutput = True

        # 确保要素类支持Z/M值
        print("检查要素类属性...")
        if not ensure_fields_with_z(Config.OLD_FEATURE_CLASS):
            raise Exception("处理旧要素类失败")

        if not ensure_fields_with_z(Config.NEW_FEATURE_CLASS):
            raise Exception("处理新要素类失败")

        # 给旧数据添加一个字段：“ADD_DATA”，设置为短整型并初始化为1
        print("给旧数据添加 ADD_DATA 字段...")
        add_field_and_initialize(Config.OLD_FEATURE_CLASS, "ADD_DATA", "SHORT", 1)

        # 把旧数据中存在而新数据中不存在的属性字段添加到新数据中，全部初始化为空
        print("同步新旧数据的字段结构...")
        add_missing_fields(Config.NEW_FEATURE_CLASS, Config.OLD_FEATURE_CLASS)

        # 将旧数据全部复制到新数据中，字段要求一一对应，旧数据没有的字段设为空
        print("开始从旧数据复制到新数据...")
        copy_old_to_new(Config.NEW_FEATURE_CLASS, Config.OLD_FEATURE_CLASS)

        print("\n===== 全部处理完成 =====")

    except Exception as e:
        print("执行过程中发生错误: %s" % str(e))
        import traceback

        traceback.print_exc()
    finally:
        # 清理临时资源
        arcpy.ClearEnvironment("workspace")